home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Commun⁄Network / Mac⁄gnuucp / Source / rmail.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-19  |  16.8 KB  |  796 lines  |  [TEXT/KAHL]

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <errno.h>
  4. #include <pascal.h>
  5.  
  6. #define MAILCMD "rmail"
  7. #define MAXTRIES 20
  8. #include "includes.h"
  9. #include "uucp.h"
  10.  
  11. #ifdef VMS
  12. #define TERMINATOR "CTRL-Z"
  13. #define MAILSTR "MAIL %s %s"
  14. #else
  15. #define MAILSTR "/bin/mail < %s %s"
  16. #define TERMINATOR "CTRL-D"
  17. #endif
  18.  
  19. void print_out(char *, int);
  20.  
  21. void
  22. print_out (str, i)
  23. char *str;
  24. int i;
  25. {
  26.     int count;
  27.     printf("String: \n");
  28.     for (count = 0; count < i; count++)
  29.         {
  30.             putchar(str[count]);
  31.             }
  32.     putchar('\n');
  33.     }
  34.  
  35. char *rmail_version = "Mac/rmail version 4.3";
  36.  
  37. int process_queue;
  38.  
  39. int doing_alias = 0;
  40.  
  41. char curr_dir[NAMESIZE];
  42.  
  43. int
  44. rmail (argc, argv)
  45. int argc;
  46. char *argv[];
  47.  
  48. {
  49.     int i;
  50.     for (i = 1; i < argc; i++) {
  51.     if (argv[i][0] != '-')
  52.         break;
  53.     switch (argv[i][1]) {
  54.  
  55.     default:
  56.         printf("rmail: unknown flag ignored\n");
  57.  
  58.     case 'x':
  59.         debug = atoi(&argv[i][2]);
  60.         printf("rmail: debug level set to %d\n", debug);
  61.         break;
  62.     case 'q':
  63.         process_queue = true;
  64.         printf("rmail: entering server mode\n");
  65.         }
  66.     }
  67.     read_params(0);
  68.  
  69.     cuserid(who);
  70.     strcpy(host_name, "rmail");
  71.  
  72.     if (Spool == NULL) {
  73.     printf("cannot read Spool directory from Control file\n");
  74.     exit(EXIT_ERR);
  75.     }
  76.     if (Sysfile == NULL) {
  77.     printf("cannot read Sysfile directory from Control file\n");
  78.     exit(EXIT_ERR);
  79.     }
  80.     if (Myname[0] == (char)NULL) {
  81.     printf("cannot read Node name from Control file\n");
  82.     exit(EXIT_ERR);
  83.     }
  84.     /* getwd(curr_dir); */
  85.  
  86.     if (chdir(Spool) != 0) {
  87.     printf("cannot change to %s\n", Spool);
  88.     perror("can't change directory");
  89.     exit(EXIT_ERR);
  90.     }
  91.     if (process_queue)
  92.             {
  93.                 do_rmail_forever();
  94.                 return(EXIT_OK);
  95.                 }
  96.         else
  97.             return(do_rmail_interactive(argc, argv));
  98.     }
  99.     
  100.     
  101. int
  102. do_rmail_interactive(argc, argv)
  103.     int argc;
  104.     char *argv[];
  105.     {
  106.         FILE *fd;
  107.         int i;
  108.         int err;
  109.         char *argvuser = NULL;
  110.         char *argvfile = NULL;
  111.         for (i = 1; i < argc; i++) {
  112.             if (argv[i][0] == '-')
  113.             continue;
  114.  
  115.         if (argvuser == NULL) 
  116.             {
  117.                 argvuser = argv[i];
  118.                 continue;
  119.                 }
  120.         if (argvuser != NULL) 
  121.             {
  122.                 argvfile = argvuser;
  123.                 argvuser = argv[i];
  124.                 break;
  125.                 }
  126.         }
  127.  
  128.         if (argvuser == NULL) 
  129.             {
  130.                 printf("usage: rmail [-xN] [file] \"site!site!...user[@site]\"\n");
  131.                 exit(EXIT_ERR);
  132.                 }
  133.         for (i = 0; i < argc; i++)
  134.         DEBUG(2, "arg=%s\n", argv[i]);
  135.  
  136.         DEBUG(5, "user=%s\n", (argvuser == NULL ? "NULL" : argvuser));
  137.         DEBUG(5, "file=%s\n", (argvfile == NULL ? "NULL" : argvfile));
  138.         if (argvfile == NULL) 
  139.             {
  140.                 mlogit("Can't find input file for", "RMAIL");
  141.                 exit(EXIT_ERR);
  142.                 /* argvfile = "stdin";
  143.                 fd = stdin; */
  144.                 } 
  145.             else
  146.             {
  147.                 if ((fd = fopen(argvfile, "r")) == NULL) 
  148.                     {
  149.                         mlogit("CAN'T OPEN", argvfile);
  150.                         perror("can't open file for reading");
  151.                         exit(EXIT_ERR);
  152.                         }
  153.                 }
  154.         /* if (fd == stdin)
  155.             printf("\nEnter Message terminated with %s\n", TERMINATOR); */
  156.         err = do_one_rmail(argvuser, argvfile, fd);
  157.         if (fd != stdin)
  158.             {
  159.                 fclose(fd);
  160.                 FlushVol(NULL, 0);
  161.                 }
  162.         return(err);
  163.         }
  164.     
  165. char *strip_local_host (address)
  166. char *address;
  167.     {
  168.         int delim;
  169.         char tmp_address[1024];
  170.         delim = mindex(address, '!');
  171.         if ( (delim > 0) &&
  172.              ( (strncmp(address, Myname, strlen(Myname)) == 0) ||
  173.                (strncmp(address, Mynamealias, strlen(Myname)) == 0)))
  174.             {
  175.                 strcpy(tmp_address, address+delim+1);
  176.                 strcpy(address, tmp_address);
  177.                 }
  178.         delim = mindex(address, '@');
  179.         if ( (delim > 0) &&
  180.                 ( (strcmp(address+delim+1, Myname) == 0) ||
  181.                (strcmp(address+delim+1, Mynamealias) == 0) ) )
  182.            {
  183.                    address[delim] = '\0';
  184.                    }
  185.          return(address);
  186.          }
  187.    
  188. int known_host (address)
  189. char *address;
  190.     {
  191.         int delim;
  192.         char host[255];
  193.         int retval = 0;
  194.         delim = mindex(address, '!');
  195.         if (delim > 0)
  196.             {
  197.                 strncpy(host, address, delim);
  198.                 host[delim]='\0';
  199.                 retval = validate_site(host, 0);
  200.                 }
  201.         if (retval == EXIT_ERR)
  202.             {
  203.                 retval = 0;
  204.                 }
  205.         return(retval);
  206.         }
  207.  
  208. int
  209. string_contains(st1, st2)
  210. char *st1;
  211. char *st2;
  212. {
  213.     int c1;
  214.     int c2;
  215.     int len1;
  216.     int len2;
  217.     int success;
  218.     len1 = strlen(st1);
  219.     len2 = strlen(st2);
  220.     success = 1;
  221.     for (c2 = 0; c2 < len2; c2++)
  222.         {
  223.             success = 1;
  224.             for (c1 = 0; c1 < len1; c1++)
  225.                 {
  226.                     if (st1[c1] == st2[c2])
  227.                         {
  228.                             c2++;
  229.                             if (c2 > len2)
  230.                                 {
  231.                                     success = 0;
  232.                                     break;
  233.                                     }
  234.                             }
  235.                         else
  236.                         {
  237.                             success = 0;
  238.                             break;
  239.                             }
  240.                     }
  241.              if (success == 1)
  242.                  break;
  243.             }
  244.     return(success);
  245.     }
  246.                                 
  247. int
  248. do_one_rmail(argvuser, argvfile, fd)
  249. char *argvuser;
  250. char *argvfile;
  251. FILE *fd;
  252.     {
  253.         int i;
  254.         int local;
  255.         int seq;
  256.         char rmtsite[80];
  257.         char rmtuser[80];
  258.         char local_data[255];
  259.         char tmp_str[255];
  260.         char *cp, data[40], datetime[40];
  261.         char c, user[40], line[NAMESIZE];
  262.         char filebuf[255];
  263.         char recipient[255];
  264.         long nread;
  265.         unsigned long temptime;
  266.         FILE *tfd;
  267.         local = 0;
  268.         strcpy(recipient, argvuser);
  269.     /* if you can't find a "!" or an @, assume local delivery */
  270.         argvuser = strip_local_host(recipient);
  271.         if ((i = mindex(argvuser, '!')) <= 0 &&
  272.             (i = mindex(argvuser, '@')) <= 0 )
  273.             {
  274.                 argvuser = argvuser + i+1;
  275.                 strcpy(rmtsite, "tmp");    /* VMS needs this or filenames aren't legal */
  276.                 local++;
  277.                 } 
  278.             else 
  279.             {
  280.                 rmtsite[0] = '\0';
  281.                 if (!known_host(argvuser))
  282.                     {
  283.                         strcpy(rmtsite, Forwarder);
  284.                         strcpy(rmtuser, &argvuser[0]);
  285.                         }
  286.                     else
  287.                       {
  288.                           strcat(rmtsite, argvuser);
  289.                         rmtsite[i] = '\0';
  290.                         strcpy(rmtuser, &argvuser[i+1]);
  291.                         }
  292.                 if (validate_site(rmtsite, 1) != EXIT_OK)
  293.                     {
  294.                         local++;
  295.                         strcpy(rmtsite, "");
  296.                         strcpy(argvuser, postmaster);
  297.                         }
  298.                 }
  299.         sprintf(tmp_str, "D.%.30sA", munge_filename(rmtsite));
  300.         seq = get_seq(Spool, data);
  301.         HandleEvents();
  302.         /* sprintf(data, "D.%.7sA%04d", rmtsite, seq); */
  303.         sprintf(data, "%s%04d", tmp_str, seq);
  304.         sprintf(local_data, "%s:%s", Spool, data);
  305.         DEBUG(2, "Using data name %s\n", local_data);
  306.  
  307.         if ((tfd = fopen(local_data, "wb")) == NULL) 
  308.             {
  309.                 mlogit("CAN'T CREATE", local_data);
  310.                 fprintf(stderr, "errno = %x\n", errno);
  311.                 perror("can't open file for writing");
  312.                 exit(EXIT_ERR);
  313.                 }
  314.         time(&temptime);
  315.         sprintf(datetime, "%s%s", currtime(), Timezone);
  316.         for (cp = datetime; *cp != '\n'; cp++);
  317.         *cp = ' ';
  318.  
  319.         /* forward to rmtsite */
  320.         cuserid(user);        /* who am I ? */
  321.         HandleEvents();
  322.         for (cp = user; *cp; cp++)
  323.         if (isupper(*cp))
  324.             *cp = tolower(*cp);
  325.  
  326.         DEBUG(2, "reading %s\n", argvfile);
  327.  
  328.         /* copy data into spool file */
  329.         /* Get first line or first 255 chars */
  330.         i = 0;
  331.         while ( ((c = fgetc(fd)) != EOF) && (i < 255) && (c != '\n'))
  332.         {
  333.             HandleEvents();
  334.             tmp_str[i] = c;
  335.             i++;
  336.             }
  337.         tmp_str[i] = '\0';
  338.         /* Found one line and it begins with "From " */
  339.         if ((c == '\n') && (strncmp("From ", tmp_str, 5) == 0))
  340.             {
  341.                 char *name_end;
  342.                 char *remote_node;
  343.                 char remote_name[255];
  344.                 char user_name[255];
  345.                 char new_user_name[255];
  346.                 sscanf(tmp_str+5, "%s", user_name);
  347.                 remote_node = strstr(tmp_str, "remote from");
  348.                 if (remote_node != NULL)
  349.                     {
  350.                         remote_node = remote_node + 12;
  351.                         sscanf(remote_node, "%s", remote_name);
  352.                         if (strcmp(remote_name, Myname) == 0)
  353.                             sprintf(new_user_name, "%s", user_name);
  354.                            else
  355.                                sprintf(new_user_name, "%s!%s", remote_name, user_name);
  356.                         }
  357.                     else
  358.                     {
  359.                         strcpy(new_user_name, user_name);
  360.                         }
  361.                 fprintf(tfd, "From %s %s remote from %s\n", 
  362.                               new_user_name, datetime, Myname);
  363.                 if (doing_alias == 0)
  364.                     {
  365.                         fprintf(tfd, "Received: by %s (Mac/gnuucp v4.3) %s\n", 
  366.                                        Myname, datetime);
  367.                         }
  368.                 }
  369.             else
  370.                 {
  371.                     if (doing_alias == 0)
  372.                         {
  373.                             fprintf(tfd, "Received: by %s (Mac/gnuucp v4.3) %s\n", 
  374.                                               Myname, datetime);
  375.                             }
  376.                     fprintf(tfd, "%s", tmp_str);
  377.                     if (tmp_str[strlen(tmp_str)-1] != '\n')
  378.                         fputc('\n', tfd);
  379.                     }
  380.          while (!feof(fd))
  381.         {
  382.             nread = fread(filebuf, sizeof(char), 255L, fd);
  383.             HandleEvents();
  384.             /* printf("Read: %ld chars from %s to %s\n", 
  385.                         nread, argvfile, local_data); */
  386.             if (nread > 0)
  387.                 fwrite(filebuf, sizeof(char), nread, tfd);
  388.             if (ferror(fd))
  389.                 mlogit("Error reading file", argvfile);
  390.             if (ferror(tfd))
  391.                 mlogit("Error writing file", local_data);
  392.             }
  393.  
  394.             DEBUG(2, "%s read\n", argvfile);
  395.         if (fclose(tfd))
  396.             mlogit("Can't close:", local_data);
  397.         HandleEvents();
  398.         if (local)
  399.             {
  400.                 if (aliasp(argvuser))
  401.                     return(deliver_alias(argvuser, local_data));
  402.                   else
  403.                     return(deliver(argvuser, local_data));
  404.                     }
  405.             else
  406.                 {
  407.                     /* Send a copy to our local postmaster */
  408.                     if ( (string_contains(postmaster, rmtuser) > 0) ||
  409.                          (string_contains("Postmaster", rmtuser) > 0) ||
  410.                          (string_contains("POSTMASTER", rmtuser) > 0) ||
  411.                          (string_contains("daemon", rmtuser) > 0) ||
  412.                          (string_contains("Daemon", rmtuser) > 0) ||
  413.                          (string_contains("DAEMON", rmtuser) > 0) )
  414.                          {
  415.                              doing_alias++;
  416.                              do_rmail(postmaster, local_data, NULL_DEVICE);
  417.                              doing_alias--;
  418.                              }
  419.                     return(forward(rmtsite, rmtuser, data, user, seq));
  420.                     }
  421.             }
  422.  
  423. int
  424. aliasp (name)
  425. char *name;
  426. {
  427.     int retval;
  428.     FILE *fd;
  429.     char filename[255];
  430.     retval = 0;
  431.     if (strcmp(name, "") != 0)
  432.         {
  433.             sprintf(filename, "%s:%s", Alias, name);
  434.             if (fd = fopen(filename, "r"))
  435.             {
  436.                 retval = 1;
  437.                 fclose(fd);
  438.                 }
  439.             }
  440.     return(retval);
  441.     }
  442.  
  443. int
  444. deliver_alias (name, input)
  445. char *name;
  446. char *input;
  447. {
  448.     char filename[255];
  449.     char newname[255];
  450.     char in_line[255];
  451.     char *to_tokenize;
  452.     FILE *fd;
  453.     int    retval;
  454.     int err;
  455.     retval = EXIT_OK;
  456.     doing_alias = doing_alias + 1;
  457.     sprintf(filename, "%s:%s", Alias, name);
  458.     if (!(fd = fopen(filename, "r")))
  459.         mlogit("Mail error can't open", filename);
  460.     while (!feof(fd))
  461.     {
  462.         strcpy(in_line, "");
  463.         fgets(in_line, 255, fd);
  464.         if (in_line[strlen(in_line)-1] == '\n')
  465.             in_line[strlen(in_line)-1] = '\0';
  466.         if ((strcmp(in_line, "") != 0) && 
  467.             (in_line[0] != '#'))
  468.             {
  469.                 if (((sscanf(in_line, "%s", newname)) != 0) && 
  470.                         strcmp(newname, "") != 0)
  471.                     {
  472.                         err = do_rmail(newname, input, NULL_DEVICE);
  473.                         if (err != EXIT_OK)
  474.                             retval = err;
  475.                         }
  476.                 }
  477.             }
  478.     doing_alias = doing_alias - 1;
  479.     fclose(fd);
  480.     remove(input);
  481.     FlushVol(NULL, 0);
  482.     return(retval);
  483.     }
  484.         
  485.         
  486. int
  487. forward(rmtsite, rmtuser, dfile, user, seq)
  488. char *rmtsite, *rmtuser, *dfile, *user;
  489. int seq;
  490.  
  491. {
  492.     FILE *fbfile, *fcfile;
  493.     char tmp_str[255];
  494.     char bfile[40], cfile[40];
  495.     char umbfile[40], umcfile[40];
  496.     char umdfile[40];
  497.     char rmtdfile[40], rmtxfile[40];
  498.     char tmp[132];
  499.  
  500.     /* create a Bfile and Cfile. Dfile already exists  */
  501.     strcpy(umdfile, unmunge_filename(dfile));
  502.     sprintf(bfile, "B.%.30sA%04d", munge_filename(Myname), seq);
  503.     sprintf(cfile, "C.%.30sA%04d", munge_filename(rmtsite), seq);
  504.     sprintf(umbfile, "B.%.30sA%04d", Myname, seq);
  505.     sprintf(umcfile, "C.%.30sA%04d", rmtsite, seq);
  506.  
  507.     sprintf(rmtxfile, "X.%.7sA%04d", Myname, seq);
  508.     sprintf(rmtdfile, "D.%.7sA%04d", rmtsite, seq);
  509.  
  510.     /* The Bfile... */
  511.     sprintf(tmp_str, "%s:%s", Spool, bfile);
  512.     if ((fbfile = fopen(tmp_str, "wb")) == NULL) {
  513.     perror("cannot open bfile for writing");
  514.     return(EXIT_ERR);
  515.     }
  516.     fprintf(fbfile, "U %s %s\n", user, Myname);
  517.     fprintf(fbfile, "F %s\n", rmtdfile);
  518.     fprintf(fbfile, "I %s\n", rmtdfile);
  519.  
  520.     fprintf(fbfile, "C %s %s\n", MAILCMD, rmtuser);
  521.  
  522.     if (fclose(fbfile) == EOF) {
  523.     printf("cannot close cfile\n");
  524.     return(EXIT_ERR);
  525.     }
  526.     /* The Cfile... */
  527.  
  528.     sprintf(tmp_str, "%s:%s", Spool, cfile);
  529.        if ((fcfile = fopen(tmp_str, "wb")) == NULL) {
  530.     perror("cannot open cfile for writing");
  531.     return(EXIT_ERR);
  532.     }
  533.     fprintf(fcfile, "S %s %s %s - %s 0666\n", umdfile, rmtdfile, user, umdfile);
  534.     fprintf(fcfile, "S %s %s %s - %s 0666\n", umbfile, rmtxfile, user, umbfile);
  535.  
  536.     if (fclose(fcfile) == EOF) {
  537.     perror("cannot close fcfile\n");
  538.     return(EXIT_ERR);
  539.     }
  540.     sprintf(tmp, "C %s %s", MAILCMD, rmtuser);
  541.     mlogit("XQT QU'ED", tmp);
  542.     return(EXIT_OK);
  543. }
  544.  
  545. int
  546. validate_site(name, errp)
  547. char *name;
  548. int errp;
  549.  
  550. {
  551.     char tmp[NAMESIZE];
  552.     FILE *fd;
  553.     int found = 0;
  554.  
  555.     if ((fd = fopen(Sysfile, "r")) == NULL) {
  556.     printf("cannot open %s\n", Sysfile);
  557.     mlogit("FAIL", "can't read Sysfile");
  558.     exit(EXIT_ERR);
  559.     }
  560.     while (fgets(tmp, sizeof(tmp), fd) != NULL)
  561.     if (strncmp(tmp, name, strlen(name)) == 0) {
  562.         found = 1;
  563.         break;
  564.     }
  565.     if (fclose(fd)) {
  566.     printf("can't close %s\n", Sysfile);
  567.     }
  568.     if (!found) 
  569.         {
  570.             if (errp)
  571.                 {
  572.                     printf("%s -- unknown site\n", name);
  573.                     mlogit("FAIL", "bad site");
  574.                     }
  575.             return(EXIT_ERR);
  576.             }
  577.     /* exit(EXIT_ERR);*/
  578.     return(EXIT_OK);
  579. }
  580.  
  581.  /* Deliver file using local mailer If mail fails, send to it to postmaster.
  582.   * If that fails, give up and die */
  583.  
  584. int
  585. deliver(addressee, data)
  586. char *addressee;
  587. char *data;
  588.  
  589. {
  590.     int mail_err;
  591.     char line[NAMESIZE];
  592.     char tmp_str[255];
  593.       /* Invoke the mailer */
  594.     if (  ((mail_err = mail("mail", addressee, data)) != EXIT_OK) &&
  595.           (strcmp(postmaster, addressee) == 0) )
  596.           {
  597.             sprintf(line, "%s %s %s", "mail", addressee, data);
  598.             mlogit("FAILED", line);
  599.             doing_alias++;
  600.             if (do_rmail(postmaster, data, NULL_DEVICE) != EXIT_OK)
  601.                 /* mail("mail", postmaster, data) != EXIT_OK) */
  602.                 {
  603.                     doing_alias--;
  604.                     sprintf(line, "%s %s %s", "mail", postmaster, data);
  605.                     mlogit("FAILED", line);
  606.                     exit(EXIT_ERR);
  607.                     }
  608.                 else
  609.                     doing_alias--;
  610.             }
  611.     sprintf(line, "%s %s %s", "mail", addressee, data);
  612.     mlogit("OK", line);
  613.     if (remove(data) == 0)
  614.             mlogit("DELETED", data);
  615.         else
  616.             {
  617.                 mlogit("CAN'T DELETE", data);
  618.                 printf("\nErrno: %d\n", errno);
  619.                 }
  620.     return(mail_err);
  621. }
  622.  
  623. #define MAXOPENS 5
  624.  
  625. int
  626. mail (command, addressee, input)
  627. char *command, *addressee, *input;
  628.  
  629. {
  630.     char line[255];
  631.     char tmp_out[255];
  632.     FILE *out;
  633.     FILE *in;
  634.     int c;
  635.     int i;
  636.     int status;
  637.     long nread;
  638.     char filebuf[255];
  639.     sprintf(tmp_out, "%s:%s", Mail, addressee);
  640.     for (i = 0; i< MAXOPENS; i++)
  641.         {
  642.             /* Some one else may have the mail file open */
  643.             DEBUG(4, "Trying to open: %s\n", tmp_out);
  644.             if ((out = fopen(tmp_out, "a")) != NULL)
  645.             {
  646.                 break;
  647.                 }
  648.             gnusleep(1);
  649.         }
  650.     if (out == NULL)
  651.         {
  652.             DEBUG(0, "Couldn't open: %s\n", tmp_out);
  653.             return(EXIT_ERR);
  654.             }
  655.     if ((in = fopen(input, "r")) == NULL)
  656.         {
  657.             DEBUG(4, "Couldn't open: %s\n", input);
  658.             fclose(out);
  659.             return(EXIT_ERR);
  660.             }
  661.     /* while ((c = fgetc(in)) != EOF)
  662.         {
  663.             HandleEvents();
  664.             fputc(c, out);
  665.             } */
  666.     while (!feof(in))
  667.         {
  668.             nread = fread(filebuf, sizeof(char), 255, in);
  669.             HandleEvents();
  670.             if (nread > 0)
  671.                 fwrite(filebuf, sizeof(char), nread, out);
  672.             if (ferror(in))
  673.                 mlogit("Error reading file", input);
  674.             if (ferror(out))
  675.                 mlogit("Error reading file", tmp_out);
  676.             }
  677.  
  678.        fputc(255, out);
  679.     fputc('\r', out);
  680.     fclose(in);
  681.     fclose(out);
  682.     return(EXIT_OK);
  683. }
  684.  
  685. int
  686. get_seq(dir, partial)
  687. char *dir;
  688. char *partial;
  689. {
  690.     /* pick a random num and make a unique file name from it /* FIXME: How do
  691.      * real systems do this? What about ensuring uniqueness at the remote
  692.      * site? */
  693.  
  694.     int i;
  695.     int seq;
  696.     char file[255];
  697.  
  698.     for (i = 0; i <= MAXTRIES; i++) {
  699.     seq = (rand()*9999.0)/RAND_MAX;
  700.     sprintf(file, "%s:%s%04d", dir, partial, seq);
  701.     if (access(file, 0) != 0)    /* doesn't already exist */
  702.         return seq;
  703.     }
  704.     if (i == MAXTRIES) {
  705.         printf("can't generate unique file name\n");
  706.         exit(EXIT_ERR);
  707.     }
  708. }
  709.  
  710. int
  711. do_rmail_forever ()
  712.     {
  713.         long i;
  714.         EventRecord event;
  715.         while (true)
  716.             {
  717.                 do_rmail_queue();
  718.                 gnusleep(10);
  719.                 }
  720.                 
  721.         }
  722.  
  723. int
  724. do_rmail_queue ()
  725. {
  726.     char *work;
  727.     FILE *fd;
  728.     int len;
  729.     char work_str[255];
  730.     char user[255];
  731.     char file[255];
  732.     while (work_scan(NULL, "RMAIL"))
  733.         {
  734.             HandleEvents();
  735.             work = work_next();
  736.             sprintf(work_str,"%s:%s", Spool, work);
  737.             fd = fopen(work_str, "r");
  738.             if (fd == NULL)
  739.                 {
  740.                     mlogit("Couldn't open RMAIL work file", work_str);
  741.                     return(1);
  742.                     }
  743.             /* fscanf(fd, "%s%s", user, file); */
  744.             fgets(file, 255, fd);
  745.             len = strlen(file);
  746.             if (file[len-1] = '\n')
  747.                 {
  748.                     file[len-1] = '\0';
  749.                     }
  750.             fgets(user, 255, fd);
  751.             len = strlen(user);
  752.             if (user[len-1] = '\n')
  753.                 {
  754.                     user[len-1] = '\0';
  755.                     }
  756.             fclose(fd);
  757.             fd = fopen(file, "r");
  758.             if (fd == NULL)
  759.                 {
  760.                     mlogit("Couldn't open RMAIL input file", file);
  761.                     return(EXIT_ERR);
  762.                     }
  763.             if (do_one_rmail(user, file, fd) == EXIT_OK)
  764.                 {
  765.                     fclose(fd);
  766.                     remove(work_str);
  767.                     remove(file);
  768.                     }
  769.                 else
  770.                     {
  771.                         fclose(fd);
  772.                         mlogit("Couldn't send mail for work file", work_str);
  773.                         return(EXIT_ERR);
  774.                         }
  775.             
  776.             }
  777.         return(0);
  778.     }
  779.     
  780.  
  781. int
  782. do_rmail (addressee, input, output)
  783. char *addressee;
  784. char *input;
  785. char *output;
  786.     {
  787.         int argc;
  788.         char *argv[5];
  789.         argc = 3;
  790.         argv[0] = "";
  791.         argv[2] = addressee;
  792.         argv[1] = input;
  793.         /* argv[2] = output; */
  794.         return(rmail(argc, argv));
  795.         }
  796.